use anyhow::Ok;
use sea_orm::{ColumnTrait, EntityTrait, QueryFilter, Set};

use super::bean;

pub async fn save_projects(
    gitlab_info_id: i32,
    project_list: Vec<bean::Project>,
) -> anyhow::Result<()> {
    let rows: Vec<dao::project_info::ActiveModel> = project_list
        .iter()
        .map(|e| dao::project_info::ActiveModel {
            gitlab_info_id: Set(gitlab_info_id),
            project_id: Set(e.id),
            project_name: Set(e.name.to_owned()),
            web_url: Set(Some(e.web_url.to_owned())),
            create_time: Set(Some(e.created_at.naive_utc())),
            ..Default::default()
        })
        .collect();
    dao::prelude::ProjectInfo::insert_many(rows)
        .exec(&common::get_conn())
        .await?;
    Ok(())
}

pub async fn find_project(id: i32) -> anyhow::Result<Option<dao::project_info::Model>> {
    let r = dao::prelude::ProjectInfo::find_by_id(id)
        .one(&common::get_conn())
        .await?;
    Ok(r)
}

pub async fn list_project(gitlab_info_id: i32) -> anyhow::Result<Vec<dao::project_info::Model>> {
    let result = dao::prelude::ProjectInfo::find()
        .filter(dao::project_info::Column::GitlabInfoId.eq(gitlab_info_id))
        .all(&common::get_conn())
        .await?;
    Ok(result)
}

pub async fn save_commits(
    project: &dao::project_info::Model,
    commit_list: &Vec<bean::Commit>,
) -> anyhow::Result<()> {
    let rows: Vec<dao::commit_info::ActiveModel> = commit_list
        .iter()
        .map(|item| dao::commit_info::ActiveModel {
            gitlab_info_id: Set(project.gitlab_info_id),
            project_id: Set(project.id as i64),
            branch: Set(item.branch.clone()),
            commit_id: Set(Some(item.id.to_owned())),
            title: Set(Some(item.title.to_owned())),
            author_email: Set(Some(item.author_email.to_owned())),
            author_name: Set(Some(item.author_name.to_owned())),
            crateed_at: Set(Some(item.created_at.naive_local())),
            additions: Set(Some(item.stats.additions as i64)),
            deletions: Set(Some(item.stats.deletions as i64)),
            total: Set(Some(item.stats.total as i64)),
            ..Default::default()
        })
        .collect();

    let count = rows.len() / 1000;
    for i in 0..count {
        let start = i * 1000;
        let current = &rows[start..start + 1000];
        dao::prelude::CommitInfo::insert_many(current.to_vec())
            .exec(&common::get_conn())
            .await?;
    }
    if rows.len() % 1000 != 0 {
        let current = &rows[count * 1000..rows.len()];
        dao::prelude::CommitInfo::insert_many(current.to_vec())
            .exec(&common::get_conn())
            .await?;
    }
    Ok(())
}
